package com.wolfking.jeesite.util;

import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class RequestUtil {

    public static String getRequestUrl(HttpServletRequest request, String... removeParameters) {
        String requestUrl = request.getRequestURL().toString();
        Map<String, String> parameterMap = Maps.newHashMap();
        if(StringUtils.isNotBlank(request.getQueryString())) {
            try {
                Arrays.stream(request.getQueryString().split("&")).filter(StringUtils::isNotBlank)
                        .map(s -> s.split("=")).forEach(s -> {
                            if (StringUtils.isNoneBlank(s[0])) {
                                parameterMap.put(s[0], s.length == 1 ? "" : s[1]);
                            }
                        });
                Arrays.stream(removeParameters).forEach(parameterMap::remove);
                if (!parameterMap.isEmpty()) {
                    String queryParam = parameterMap.entrySet().stream()
                            .map(e -> e.getKey() + "=" + e.getValue())
                            .reduce("", (e1, e2) -> e1 + "&" + e2);
                    requestUrl += "?" + queryParam.substring(1);
                }
            } catch (Exception e) {
                log.warn("", e);
            }
        }
        return requestUrl;
    }

    public static Map<String, Object> getRequestParameters(HttpServletRequest request) {
        Map<String, Object> params = Maps.newHashMap();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String s = parameterNames.nextElement();
            String parameter = request.getParameter(s);
            if (StringUtils.isNotBlank(parameter)) {
                parameter = StringUtils.isBlank(parameter) ? "" : parameter;
                params.put(s, parameter);
                try {
                    JsonElement element = JsonParser.parseString(parameter);
                    if (element.isJsonArray() || element.isJsonObject()) {
                        params.put(s, element);
                    }
                } catch (Exception e) {
                }
            }
        }
        return params;
    }

    public static Map<String, String> getRequestHeaders(HttpServletRequest request) {
        Map<String, String> params = Maps.newHashMap();
        Enumeration<String> parameterNames = request.getHeaderNames();
        while (parameterNames.hasMoreElements()) {
            String s = parameterNames.nextElement();
            String parameter = request.getParameter(s);
            parameter = StringUtils.isBlank(parameter) ? "" : parameter;
            params.put(s, parameter);
        }
        return params;
    }

    public static Map<String, Cookie> getRequestCookies(HttpServletRequest request) {
        Map<String, Cookie> params = Maps.newHashMap();
        Cookie[] cookies = request.getCookies();
        if (Objects.nonNull(cookies)) {
            for (Cookie cookie : cookies) {
                params.put(cookie.getName(), cookie);
            }
        }
        return params;
    }


    public static String getRequestUrlEncode(HttpServletRequest request) {
        String requestUrl = request.getRequestURL().toString();
        if (StringUtils.isNotBlank(request.getQueryString()))
            requestUrl = requestUrl + "?" + request.getQueryString();
        try {
            return URLEncoder.encode(requestUrl, "utf-8");
        } catch (Exception e) {
            return requestUrl;
        }
    }

    public static String getRequestUrlEncode(HttpServletRequest request, String... removeParameters) {
        if (removeParameters.length == 0) {
            return getRequestUrlEncode(request);
        }
        String requestUrl = getRequestUrl(request, Maps.newHashMap(), removeParameters);
        try {
            return URLEncoder.encode(requestUrl, "utf-8");
        } catch (Exception e) {
            return requestUrl;
        }
    }

    public static String getRequestUrl(HttpServletRequest request, Map<String, String> queryMap, String... removeParameters) {
        if (removeParameters.length == 0) {
            return getRequestUrlEncode(request);
        }
        String requestUrl = request.getRequestURL().toString();
        Map<String, String[]> parameterMap = Maps.newHashMap(request.getParameterMap());
        for (String parameter : removeParameters) {
            parameterMap.remove(parameter);
        }
        queryMap.forEach((k, v) -> parameterMap.put(k, new String[]{v}));
        if (!parameterMap.isEmpty()) {
            String queryParam = parameterMap.entrySet().stream()
                    .map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
                    .reduce("", (e1, e2) -> e1 + "&" + e2);
            requestUrl += "?" + queryParam.substring(1);
        }
        return requestUrl;
    }
}
